<?php

Raise::load('core.RaiseStaticClass');
/**
 * RaisePath class
 * for functionalities related to paths
 *
 * @author Sam-Mauris Yong <hellclanner at live dot com>
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package Raise.Core.IO
 * @since 1.2
 */
class RaisePath extends RaiseStaticClass {

    /**
     * Get the directory name
     */
    const DIRECTORY = 'dirname';

    /**
     * Get the filename
     */
    const BASENAME = 'basename';

    /**
     * Get the file extension
     */
    const EXTENSION = 'extension';

    /**
     * Get the file name without the file extension
     */
    const FILENAME = 'filename';

    /**
     * Combine two paths into an elaborated path
     * @param string $path If left empty, the path will be worked from the current working path. See RaisePath::currentWorkingPath()
     * @param string $relative The relative path that will navigate from $path. e.g. '../../test/example/run.html'
     * @return string The final combined path
     */
    public static function combine($path, $relative){
        $relative = str_replace(array('\\','\\\\','//'), '/', trim($relative));
        $path = str_replace(array('\\','\\\\','//'), '/', trim($path));
        if($path == ''){
            $path = self::currentWorkingPath();
        }
        if(substr($path,-1,1) == '/'){
            $path = substr($path, 0, strlen($path)-1);
        }
        $relativeParts = explode('/', $relative);
        foreach($relativeParts as $p){
            if($p == ''){

            }elseif($p == '..'){
                $path = self::path($path);
            }elseif($p != '.'){
                $path .= '/' . $p;
            }
        }

        return str_replace('/', self::directorySeparator(), $path);
    }

    /**
     * Get the directory separator for the system
     * @return string
     * @static
     */
    public static function directorySeparator() {
        return DIRECTORY_SEPARATOR;
    }

    /**
     * Get the path separator for the system
     * e.g for Windows it's ';', for Linux it is ':'
     * The separator can be used to separate several paths, for example:
     * On Windows C:\windows\system32;C:\xampp\htdocs;C:\gcc\bin
     * or
     * On Linux /var/www/myfile:/tmp/myfile
     * @return string
     * @static
     */
    public static function pathSeparator() {
        return PATH_SEPARATOR;
    }

    /**
     * Get the absolute path to PHP's temp folder
     * @return string
     * @static
     */
    public static function tempPath(){
        return sys_get_temp_dir();
    }

    /**
     * Get only the file name from a path name
     * @param string $p The path name e.g. /home/user/public/test.html
     * @return string The file name e.g. test
     * @static
     * @see RaisePath::pathInfo()
     */
    public static function fileName($p){
        return self::pathInfo($p, self::FILENAME);
    }

    /**
     * Get the file name together with the file extension from a path name
     * @param string $p The path name e.g. /home/user/public/test.html
     * @return string The file name e.g. test.html
     * @static
     * @see RaisePath::pathInfo()
     */
    public static function baseName($p){
        return self::pathInfo($p, self::BASENAME);
    }

    /**
     * Get file extension from a path name
     * @param string $p The path name e.g. /home/user/public/test.html
     * @return string The file name e.g. html
     * @static
     * @see RaisePath::pathInfo()
     */
    public static function extension($p){
        return self::pathInfo($p, self::EXTENSION);
    }

    /**
     * Get only the directory path from a path name
     * @param string $p The path name e.g. /home/user/public/test.html
     * @return string The directory path e.g. /home/user/public/
     * @static
     * @see RaisePath::pathInfo()
     */
    public static function path($p){
        return self::pathInfo($p, self::DIRECTORY);
    }

    /**
     * Get information about a directory path
     * @param string $p The path name to get information abotu
     * @param string $a (optional) Particular information to retrieve. False to return all the information in an array
     * @return string|array
     * @link http://php.net/pathinfo
     */
    public static function pathInfo($p, $a = false){
        $k = pathinfo($p);
        if($a){
            return $k[$a];
        }
        return $k;
    }

    /**
     * Get the application's current working directory (usually from the application root)
     * @return string
     */
    public static function currentWorkingPath(){
        return getcwd();
    }

    /**
     * Get phpRaise's path to the core files
     * @return string
     */
    public static function phpRaiseCorePath(){
        return self::path(__FILE__);
    }

    /**
     * Get phpRaise's framework path
     * @return string
     */
    public static function phpRaisePath(){
        return self::resolve(self::path(__FILE__) . DIRECTORY_SEPARATOR . '..');
    }

    /**
     * Get the directory path of the current PHP script
     * @return string
     */
    public static function scriptPath(){
        return self::path($_SERVER['SCRIPT_FILENAME']);
    }

    /**
     * Resolves a directory path
     * @param string $p The directory path to resolve
     * @return string The resolved directory path
     * @static
     */
    public static function resolve($p){
        return realpath($p);
    }

    /**
     * Fetch the path to the file containing a specific class.
     * If the class is defined in the PHP core or PHP extension, NULL
     * will be returned
     * @param string $class Name of the class
     * @return string|null
     */
    public static function classPathName($class){
        $r = new ReflectionClass($class);
        $c = $r->getFileName();
        if($c){
            return $c;
        }
        return null;
    }

}
